﻿// SlottedList class definition (child class of DragDropList)
var SlottedList = Class.create();
SlottedList.prototype = {
	initialize: function() {
		this.tagId = ""; // html tag id for DragDropList
		this.editorLookupId = ""; 
		this.listLookupId = "";  
		this.listType = 0;  // 0 = slotted or 1 = timeline
		//this.width = -1; // tbd: list width (should match width in editor - do we want lists with different widths?)
		this.itemType = -1;  // 1=package, 2=event, 3=combo, 4=asset
		this.items = [];  // array of draggablePecas in list
		this.numItems = -1; // number of items in list
		this.numIntervals = -1  // number of intervals in slotted list
		this.listIndex = -1;  // index of this list in the editor
		this.request = null;  // ajax request
		this.loaded = false;  // initialize loaded to false
		this.deleted = false;  // to track when items have been deleted by ajax call
		this.xml = null; // editor page xml containing list spots
		this.openRequest = null;
		this.keepOpenRequest = null;
		this.closeRequest = null;
		this.editTimer = null;
	},
	
	// function to load list properties and make call to DB
	load: function (tagId, editorLookupId, listLookupId, itemType, numIntervals, listIndex, xml) {
		// initialize properties
		this.tagId = tagId;
		this.editorLookupId = ""; 
		this.listLookupId = listLookupId;
		this.itemType = itemType;
		this.numIntervals = numIntervals;		
		this.listIndex = listIndex;
		this.xml = xml;
		
		//this.cachedScheduleForEditKeepOpen = this.scheduleForEditKeepOpen.bindAsEventListener(this);
	},
	
	// function to render the list and attach to editor (only to be called once)
	render: function() {
		// render drop cells
		var listContainer = document.createElement('div');
		listContainer.className = 'col';
		listContainer.style.width = (activeEditor.cellWidth + activeEditor.cellPadding*2) + "px";
		listContainer.id = this.tagId;
		var itemIndex = 0;
        for (var i=0; i<this.numIntervals; i++) {
	    	var cellNode = document.createElement('div');
	    	cellNode.className = 'dropCell';
	    	cellNode.id = this.tagId + "_drop_" + i;
	    	cellNode.style.width = (activeEditor.cellWidth + activeEditor.cellPadding*2) + "px";
	    	cellNode.style.height = activeEditor.cellHeight + "px";
            // check if we need to render a loaded item
	    	if (itemIndex < this.items.length) {
	            if (this.items[itemIndex].parentNode.id == cellNode.id) {
	            	var dragEl = this.items[itemIndex].render();
	            	cellNode.appendChild(dragEl);
	            	itemIndex++;
	            }
            }
            // add observers to drop cells
            addDropObservers(cellNode);
            listContainer.appendChild(cellNode);
        } 
        return listContainer;
	},
	
	requestPackageSpots: function () {
	    // make request to db
	    var sProc = "<STOREDPROCEDURE Name=\"sproc_WEB_GetScheduledSpotsByDate\" DateStart=\"" + this.listLookupId + "\" />";
        var xmlStr = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
        xmlStr += "<ROOT>";
        xmlStr += sProc;
        xmlStr += "</ROOT>";
        url = "AjaxPost.aspx";
        this.request = new XMLHttpRequest();
        this.request.open('POST', url, true);
        this.request.setRequestHeader("Content-Type", "text/xml");
        this.request.send(xmlStr);
        this.request.onreadystatechange = this.processLoadStateChange.bindAsEventListener(this);
		$('pageContainer').addClassName('fadedBG');
		$('loadingMsg').style.display = "block";      
	},
	
	// ajax state change handler
	processLoadStateChange: function () {
		if (this.request.readyState == 4) {
			if (this.request.status == 200) {
			    this.scheduleForEditOpen();
			    if (this.request.responseXML != null) {
			        this.loadItems();
			    }
				this.loaded = true;
		        activeEditor.activateDD();
			}
		} 
	},
	
	// function to call sproc to open a schedule for edit
	scheduleForEditOpen: function () {
	    scheduleForEditOpen(this.listIndex, this.listLookupId);
	},
	
	// function to show popup of open for user edit
    showOpenForEdit: function () {       
        var user = this.openRequest.responseXML.getElementsByTagName('USER')[0];
        var fName = user.getAttribute('FirstName');
        var lName = user.getAttribute('LastName');
        var email = user.getAttribute('Email');
        var phone = user.getAttribute('Phone');
        
        $('openForEdit_Span').innerHTML = "Unable to Edit";
        var label = $('openForEdit_Label');
        label.innerHTML = "The schedule for date " + this.listLookupId + " is currently being edited by " + fName + " " + lName;
        label.innerHTML += " (email: " + email + ", phone: " + phone + ").  You can view the " + objStr;
        label.innerHTML += " but will not be able to save any changes."
        $('openForEditAlert').style.display = "block";
    },
	
	// function to keep a schedule open
	scheduleForEditKeepOpen: function () {
        this.editTimer = setTimeout('scheduleForEditKeepOpen(' + this.listIndex + ')', 60000);
	
	    // make request to db to keep object open
        var sProc = "<STOREDPROCEDURE Name=\"sproc_WEB_ScheduleForEditKeepOpen\" Date=\"" + this.listLookupId + "\" />";
        keepOpenScheduleRequest = new XMLHttpRequest();
        callAjaxPost(keepOpenScheduleRequest, sProc, null);
	},
	
	scheduleForEditClose: function () {
        clearTimeout(this.editTimer);
        
        // make request to db to close object
        var sProc = "<STOREDPROCEDURE Name=\"sproc_WEB_ScheduleForEditClose\" Date=\"" + this.listLookupId + "\" />";
        var closeScheduleRequest = new XMLHttpRequest();
        var xmlStr = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
        xmlStr += "<ROOT>";
        xmlStr += sProc;
        xmlStr += "</ROOT>";
        var url = "AjaxPost.aspx";
        closeScheduleRequest = new XMLHttpRequest();
        closeScheduleRequest.open('POST', url, false);
        closeScheduleRequest.setRequestHeader("Content-Type", "text/xml");
        closeScheduleRequest.send(xmlStr);
        
        if (closeScheduleRequest.readyState == 4)
		    if (closeScheduleRequest.status == 200)
		        return;
        
        //callAjaxPost(closeScheduleRequest, sProc, null);   
    },
    		
	loadItems: function () {
 		// load draggablePecas from db
 		// for slotted lists this is packages only 
		var scheduledspots = this.request.responseXML.getElementsByTagName('SCHEDULEDSPOT');
		var packages = this.request.responseXML.getElementsByTagName('PACKAGE');
		for (var i=0, len=scheduledspots.length; i<len; i++) {
			var newPeca = new DraggablePeca();
			var timeSlot = parseXMLDate(scheduledspots[i].getAttribute('DateTime'));
			var dbId = packages[i].getAttribute('ID');
			var name = packages[i].getAttribute('Name');
			var duration = parseXMLDate(packages[i].getAttribute('Duration'));
			var systemId = packages[i].getAttribute('SystemID');
			var thisEnabled = packages[i].getAttribute('ThisEnabled');
			var thisDayPart = packages[i].getAttribute('ThisDayPart');
			var thisStartDate = parseXMLDate(packages[i].getAttribute('ThisStartDate'));
			var thisEndDate = parseXMLDate(packages[i].getAttribute('ThisEndDate'));
			var thisColor = packages[i].getAttribute('ThisColor');
			var enabledNN = packages[i].getAttribute('EnabledNN');
			var ingestedNN = packages[i].getAttribute('IngestedNN');
			var onPlayersNN = packages[i].getAttribute('OnPlayersNN');
			var dayPartNN = packages[i].getAttribute('DayPartNN');
			var startDateNN = parseXMLDate(packages[i].getAttribute('StartDateNN'));
			var endDateNN = parseXMLDate(packages[i].getAttribute('EndDateNN'));
			var htmlNN = packages[i].getAttribute('htmlNN');
			var percentBreakdownNN = packages[i].getAttribute('PercentBreakdownNN');
			var cueStringStart = packages[i].getAttribute('CueStringStart');
			var cueStringEnd = packages[i].getAttribute('CueStringEnd');			
			var openForEditUserId = packages[i].getAttribute('OpenForEditUserID');
			var openForEditDateTime = parseXMLDate(packages[i].getAttribute('OpenForEditDateTime'));
			var isWebControlPackage = packages[i].getAttribute('IsWebControlPackage')
			
			newPeca.load(this.itemType, timeSlot, this.listType, dbId, name, duration, systemId, -1, '', false, -1, 
			                thisEnabled, thisDayPart, thisStartDate, thisEndDate, thisColor, enabledNN, 
			                dayPartNN, startDateNN, endDateNN, ingestedNN, onPlayersNN, '', htmlNN, percentBreakdownNN,
			                cueStringStart, cueStringEnd, openForEditUserId, openForEditDateTime, isWebControlPackage);
			this.items.push(newPeca);
			activeEditor.draggablePecas.push(newPeca);
        }
		// check if we need to render a loaded item
		var itemIndex = 0;
		for (var i=0, len=activeEditor.timeSlots.length; i<len; i++) {
		    if (itemIndex < this.items.length) {
                if (this.compareTimes(activeEditor.timeSlots[i], this.items[itemIndex].timeSlot)) {
                    var dropId = this.tagId + "_drop_" + i;
                    var cellNode = $(dropId);
                    var dragEl = this.items[itemIndex].render();
                    cellNode.appendChild(dragEl);
                    itemIndex++;
                    // check to see if there are any alerts
                    activeEditor.validatePackage(dragEl, cellNode);
                }
            }
		}			
	},
	
	compareTimes: function (timeA, timeB) {
	    if (timeB == null) return false;  
	    timeASplit = timeA.split(':');
	    var timeAHours = timeASplit[0];
	    var timeAMinutes = timeASplit[1];
	    var timeBHours = timeB[3];
	    var timeBMinutes = timeB[4];
	    if ((timeAHours == timeBHours) && (timeAMinutes == timeBMinutes))
	        return true;
	    return false;
	},
	
	// function to save all properties to DB
	saveItems: function() {
	    var slots = $(this.tagId).immediateDescendants();
	    var xmlStr = "";
	    var sessionIdBLStr = "SessionID=\"" + sessionId + "\" ";
	    // loop through list to see if it is empty
	    var emptyList = true;
	    for (var i=0, len=slots.length; i<len; i++) {
	        if (slots[i].firstDescendant()) {
	            emptyList = false;
	            break;
	        }
	    }
	    if (emptyList == false) {
	        for (var i=0, len=slots.length; i<len; i++) {
	            var item = slots[i].firstDescendant();
	            if (item) {
	                var peca = activeEditor.getPeca(item);
	                var packageId = peca.dbId;
	                var time = activeEditor.timeSlots[i] + ":00";
	                var dateTime = this.listLookupId + " " + time;
                    xmlStr += "<BL_SCHEDULEDSPOT BLID=\"\" SystemID=\"1\" PackageID=\"" + packageId + "\" DateTime=\"" + dateTime + "\" CueString=\"\" " + sessionIdBLStr + " />";
	            }
	        }
	    } else { // insert empty row so sproc knows to delete spots for this date
	        xmlStr += "<BL_SCHEDULEDSPOT BLID=\"\" SystemID=\"1\" PackageID=\"-1\" DateTime=\"" + this.listLookupId + "\" CueString=\"\" " + sessionIdBLStr + " />";
	    } 
	    return xmlStr;
	},
	
	processDeleteStateChange: function () {
		if (this.request.readyState == 4) {
			if (this.request.status == 200) {
				this.deleted = true;
				//alert(this.listLookupId + " has deleted");
		        activeEditor.save();	
			}
		} 
	}	
	
//	// function to delete items
//	deleteItems: function () {
//	    // make request to db
//	    var sProc = "<STOREDPROCEDURE Name=\"sproc_WEB_DeleteScheduledSpotsByDate\" DateStart=\"" + this.listLookupId + "\" />";
//        var xmlStr = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
//        xmlStr += "<ROOT>";
//        xmlStr += sProc;
//        xmlStr += "</ROOT>";
//        url = "AjaxPost.aspx";
//        this.request = new XMLHttpRequest();
//        this.request.open('POST', url, false);
//        this.request.setRequestHeader("Content-Type", "text/xml");
//        this.request.send(xmlStr);
//        //this.request.onreadystatechange = this.processDeleteStateChange.bindAsEventListener(this);

//	}
}

// SlottedList class definition (child class of DragDropList)
var TimeLineList = Class.create();
TimeLineList.prototype = {
	initialize: function() {
		this.tagId = ""; // html tag id for DragDropList
		this.editorLookupId = ""; 
		this.listLookupId = "";  
		this.listType = 1;  // 0 = slotted or 1 = timeline 
		//this.width = -1; // tbd: list width (should match width in editor - do we want lists with different widths?)
		this.itemType = -1;  // 1=package, 2=event, 3=combo, 4=asset
		this.items = [];  // array of items in list
		this.numItems = -1; // number of items in list
		this.numIntervals = -1  // number of intervals in list
		this.listIndex = -1;  // index of this list in the editor
		this.request = null;  // ajax request
		this.loaded = false;  // initialize loaded to false
		this.deleted = false;  // to track when items have been deleted by ajax call
		this.xml = null; // editor page xml containing list spots
	},
	
	// function to load all properties from DB
	load: function (tagId, editorLookupId, listLookupId, itemType, numIntervals, listIndex, xml) {
		// initialize properties
		this.tagId = tagId;
		this.editorLookupId = editorLookupId;
		this.listLookupId = listLookupId;
		this.itemType = itemType;
		this.numIntervals = numIntervals;
		this.listIndex = listIndex;
		this.xml = xml;
	},
	
	// function to render the list and attach to editor (only to be called once)
	render: function() {
		// render column
		var listContainer = document.createElement('ul');
		listContainer.className = 'col';
		listContainer.style.width = (activeEditor.cellWidth + activeEditor.cellPadding*2) + "px";
		listContainer.id = this.tagId;
        // render loaded items
        for (var i=0, len=this.items.length; i<len; i++) {       
            listContainer.appendChild(this.items[i].render());
        }
        return listContainer;
	},	
		
	loadItems: function () {
 		// load draggablePecas from db
 		if (this.itemType == 2) {  // events
            var packageSpots = this.xml.getElementsByTagName('PACKAGESPOT');  		
		    for (var i=0, len=packageSpots.length; i<len; i++) {
		        // get event associated with package spot
                var eventObj = null;
                if (packageSpots[i].hasChildNodes()) { 
                    eventObj = packageSpots[i].childNodes[1];
                } else {
                    continue;
                } 
		        // create new draggable and prepare load values
			    var newPeca = new DraggablePeca();
			    var timeSlot = parseXMLDate(packageSpots[i].getAttribute('Time'));
			    var dbId = eventObj.getAttribute('ID');
			    var name = eventObj.getAttribute('Name');
			    var duration = parseXMLDate(eventObj.getAttribute('Duration'));
			    var zoneId = eventObj.getAttribute('ZoneID');
			    var thisEnabled = eventObj.getAttribute('ThisEnabled');
			    var thisDayPart = eventObj.getAttribute('ThisDayPart');
			    var thisStartDate = parseXMLDate(eventObj.getAttribute('ThisStartDate'));
			    var thisEndDate = parseXMLDate(eventObj.getAttribute('ThisEndDate'));
			    var thisColor = eventObj.getAttribute('ThisColor');
			    var enabledNN = eventObj.getAttribute('EnabledNN');
			    var dayPartNN = eventObj.getAttribute('DayPartNN');
			    var startDateNN = parseXMLDate(eventObj.getAttribute('StartDateNN'));
			    var endDateNN = parseXMLDate(eventObj.getAttribute('EndDateNN'));			
			    var ingestedNN = eventObj.getAttribute('IngestedNN');
			    var onPlayersNN = eventObj.getAttribute('OnPlayersNN');
			    var htmlNN = eventObj.getAttribute('htmlNN');
			    var cueStringStart = eventObj.getAttribute('CueStringStart');
			    var cueStringEnd = eventObj.getAttribute('CueStringEnd');			
			    var openForEditUserId = eventObj.getAttribute('OpenForEditUserID');
			    var openForEditDateTime = parseXMLDate(eventObj.getAttribute('OpenForEditDateTime'));
    			
			    newPeca.load(this.itemType, timeSlot, this.listType, dbId, name, duration, -1, zoneId, '', false, -1, 
			                thisEnabled, thisDayPart, thisStartDate, thisEndDate, thisColor, enabledNN, 
			                dayPartNN, startDateNN, endDateNN, ingestedNN, onPlayersNN, '', htmlNN, '',
			                cueStringStart, cueStringEnd, openForEditUserId, openForEditDateTime, false);
			    this.items.push(newPeca);
			    activeEditor.draggablePecas.push(newPeca);
            }
        } else if (this.itemType == 3) {  // combos & assets      
		    var eventSpots = this.xml.getElementsByTagName('EVENTSPOT');
		    for (var i=0, len=eventSpots.length; i<len; i++) {
                // get asset associated with event spot
                var asset = null;
                if ( (eventSpots[i].hasChildNodes()) && (eventSpots[i].getAttribute('ChannelID') == this.listLookupId) ) { 
                    asset = eventSpots[i].childNodes[1];
                } else {
                    continue;
                }
		        // create new draggable and prepare load values
			    var newPeca = new DraggablePeca();
			    var timeSlot = parseXMLDate(eventSpots[i].getAttribute('Time'));
			    var dbId = asset.getAttribute('ID');
			    var name = asset.getAttribute('Name');
			    var duration = parseXMLDate(asset.getAttribute('Duration'));
			    var channelsNN = asset.getAttribute('ChannelsNN');
			    var isCombo = asset.getAttribute('IsCombo');
			    var textTemplateId = asset.getAttribute('TextTemplateID');
			    var thisEnabled = asset.getAttribute('ThisEnabled');
			    var thisDayPart = asset.getAttribute('ThisDayPart');
			    var thisStartDate = parseXMLDate(asset.getAttribute('ThisStartDate'));
			    var thisEndDate = parseXMLDate(asset.getAttribute('ThisEndDate'));
			    var thisColor = asset.getAttribute('ThisColor');
			    var enabledNN = asset.getAttribute('EnabledNN');
			    var dayPartNN = asset.getAttribute('DayPartNN');
			    var startDateNN = parseXMLDate(asset.getAttribute('StartDateNN'));
			    var endDateNN = parseXMLDate(asset.getAttribute('EndDateNN'));			
			    var ingestedNN = asset.getAttribute('IngestedNN');
			    var onPlayersNN = asset.getAttribute('OnPlayersNN');
			    var colorNN = asset.getAttribute('ColorNN');
			    var htmlNN = asset.getAttribute('htmlNN');
			    var cueStringStart = asset.getAttribute('CueStringStart');
			    var cueStringEnd = asset.getAttribute('CueStringEnd');			
			    var openForEditUserId = asset.getAttribute('OpenForEditUserID');
			    var openForEditDateTime = parseXMLDate(asset.getAttribute('OpenForEditDateTime'));
    			
    			var itemType = (isCombo == '1') ? 3 : 4;
    			
			    newPeca.load(itemType, timeSlot, this.listType, dbId, name, duration, -1, -1, channelsNN, 
			                isCombo, textTemplateId, 
			                thisEnabled, thisDayPart, thisStartDate, thisEndDate, thisColor, enabledNN, 
			                dayPartNN, startDateNN, endDateNN, ingestedNN, onPlayersNN, colorNN, htmlNN, '',
			                cueStringStart, cueStringEnd, openForEditUserId, openForEditDateTime, false);
			    this.items.push(newPeca);
			    activeEditor.draggablePecas.push(newPeca);
            }        
        }
        
		// render loaded items
	    for (var i=0, len=this.items.length; i<len; i++) {
			$(this.tagId).appendChild(this.items[i].render());    	
        }	
	},

	// function to save all items to DB
	saveItems: function() {
	    var slots = $(this.tagId).immediateDescendants();
	    var xmlStr = "";
	    var cumTime = ['0','0','0','00','00','00'];  // zero out year, month, day, hour, minute, second
	    var sessionIdBLStr = "SessionID=\"" + sessionId + "\" ";
	    for (var i=0, len=slots.length; i<len; i++) {
	        var item = slots[i];
	        if (item) {
	            var peca = activeEditor.getPeca(item);
	            //var LookupId = this.listLookupId;
	            var time = "1900-01-01 " + cumTime[3] + ":" + cumTime[4] + ":" + cumTime[5];
	            //var dbId = peca.dbId;
	            if (this.itemType == 2) {  // saving events
                    if (activeEditorPageId == 'multiPackage') {
                        xmlStr += "<BL_PACKAGESPOT BLID=\"\" PackageID=\"" + this.listLookupId + "\" ZoneID=\"1\" Time=\"" + time + "\" EventID=\"" + peca.dbId + "\" " + sessionIdBLStr + "/>";
                    } else {
                        xmlStr += "<BL_PACKAGESPOT BLID=\"\" PackageID=\"" + this.editorLookupId + "\" ZoneID=\"" + this.listLookupId + "\" Time=\"" + time + "\" EventID=\"" + peca.dbId + "\" " + sessionIdBLStr + "/>";
                    }
                } else if (this.itemType == 3) { // saving combos and assets
                    xmlStr += "<BL_EVENTSPOT BLID=\"\" EventID=\"" + this.editorLookupId + "\" ChannelID=\"" + this.listLookupId + "\" Time=\"" + time + "\" AssetID=\"" + peca.dbId + "\" " + sessionIdBLStr + "/>";
                }
                cumTime = this.addTime(cumTime, peca.duration);
	        }
	    }  
	    return xmlStr;
	},
	
	// function to  two time arrays
	addTime: function (timeA, timeB) {
	    // convert to seconds
	    var timeASecs = parseInt((timeA[3]*3600),10) + parseInt((timeA[4]*60),10) + parseInt((timeA[5]),10);
	    var timeBSecs = parseInt((timeB[3]*3600),10) + parseInt((timeB[4]*60),10) + parseInt((timeB[5]),10);
	    var totalSecs = timeASecs + timeBSecs;
	    
	    // convert back to hours, minutes, seconds
	    var hours = Math.floor(totalSecs / 3600);
	    var minutes = Math.floor((totalSecs % 3600) / 60);
	    var seconds = (totalSecs % 3600) % 60;
	    return ['0','0','0',hours.toPaddedString(2,10),minutes.toPaddedString(2,10),seconds.toPaddedString(2,10)];
	}
}